package jmine.tec.utils.annotation.visitor;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Collection;

/**
 * Visitor para anotacoes em metodos
 * 
 * @author takeshi
 * @param <R> R
 */
public interface MethodAnnotationVisitor<R> {

    /**
     * Visita uma annotation em um metodo
     * 
     * @param ann a annotation
     * @param declared a classe que declara a annotation
     * @param method o method que contem a annotation
     * @return Collection de R
     */
    Collection<? extends R> onMethodAnnotation(Annotation ann, Class<?> declared, Method method);

    /**
     * Visita uma annotation em um construtor
     * 
     * @param ann a annotation
     * @param declared a classe que declara a annotation
     * @param ctor Constructor
     * @return Collection de R
     */
    Collection<? extends R> onConstructorAnnotation(Annotation ann, Class<?> declared, Constructor<?> ctor);

    /**
     * Deve devolver <code>true</code> se o metodo com a annotation passada deve ser visitado
     * 
     * @param ann {@link Annotation}
     * @param method {@link Method}
     * @param declaring {@link Class}
     * @return boolean
     */
    boolean acceptsMethod(Annotation ann, Method method, Class<?> declaring);

    /**
     * Deve devolver <code>true</code> se o construtor com a annotation passada deve ser visitado
     * 
     * @param ann {@link Annotation}
     * @param ctor {@link Constructor}
     * @param declaring {@link Class}
     * @return boolean
     */
    boolean acceptsConstructor(Annotation ann, Constructor<?> ctor, Class<?> declaring);

}
